import express from 'express';
import cors from 'cors';
import helmet from 'helmet';
import morgan from 'morgan';
import compression from 'compression';
import rateLimit from 'express-rate-limit';
import { createServer } from 'http';
import path from 'path';
import { config, validateConfig } from '@mj-pro/core-server';
import {
  mysqlConnection,
  redisConnection,
  initializeModels,
} from '@mj-pro/database';
import {
  initializePassport,
  configureJwtStrategy,
  configureLocalStrategy,
} from '@mj-pro/auth';
import { WebSocketService } from '@mj-pro/websocket';
import { generateToken } from '@mj-pro/utils';

// 获取当前工作目录
const currentDir = process.cwd();

const app = express();
const server = createServer(app);
const port = config.PORT;

// 中间件配置
if (config.HELMET_ENABLED) {
  app.use(
    helmet({
      // 配置Helmet以避免某些安全头导致的跨域问题
      crossOriginEmbedderPolicy: false,
      crossOriginOpenerPolicy: false,
      crossOriginResourcePolicy: false,
      // 禁用严格的CSP策略，避免跨域问题
      contentSecurityPolicy: false,
      // 禁用其他可能导致问题的安全头
      hsts: false,
      noSniff: false,
      referrerPolicy: false,
      xssFilter: false,
    }),
  );
}

if (config.COMPRESSION_ENABLED) {
  app.use(compression());
}

app.use(morgan('combined'));
app.use(express.json({ limit: config.MAX_FILE_SIZE }));
app.use(
  express.urlencoded({
    extended: true,
    limit: config.MAX_FILE_SIZE,
  }),
);

// CORS配置
const corsOptions = {
  origin: function (
    origin: string | undefined,
    callback: (err: Error | null, allow?: boolean) => void,
  ) {
    // 允许没有origin的请求（如移动应用、Postman等）
    if (!origin) {
      console.log('CORS: 允许无origin请求');
      return callback(null, true);
    }

    const allowedOrigins = config.CORS_ORIGIN;
    console.log(`CORS: 检查origin: ${origin}`);
    console.log(`CORS: 允许的origins: ${JSON.stringify(allowedOrigins)}`);

    // 检查是否在允许列表中
    if (allowedOrigins.includes('*') || allowedOrigins.includes(origin)) {
      console.log(`CORS: 允许origin: ${origin}`);
      callback(null, true);
    } else {
      // 检查是否匹配部分域名（支持子域名）
      const isAllowed = allowedOrigins.some((allowedOrigin) => {
        if (allowedOrigin === '*') {
          return true;
        }
        if (allowedOrigin === origin) {
          return true;
        }
        // 支持通配符子域名
        if (allowedOrigin.startsWith('*.')) {
          const domain = allowedOrigin.substring(2);
          return origin.endsWith(domain);
        }
        return false;
      });

      if (isAllowed) {
        console.log(`CORS: 允许origin: ${origin}`);
        callback(null, true);
      } else {
        console.warn(`CORS: 阻止origin: ${origin}`);
        callback(null, false);
      }
    }
  },
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH'],
  allowedHeaders: [
    'Content-Type',
    'Authorization',
    'X-Requested-With',
    'X-Forwarded-For',
    'X-Real-IP',
    'Accept',
    'Origin',
  ],
  exposedHeaders: [
    'Content-Length',
    'X-Requested-With',
    'Access-Control-Allow-Origin',
  ],
  // 添加额外的CORS配置
  preflightContinue: false,
  optionsSuccessStatus: 204,
  maxAge: 86400, // 预检请求缓存24小时
};

// 使用统一的CORS配置
app.use(cors(corsOptions));

// WebSocket路由 - CORS已由全局中间件处理
app.use('/ws', (req, res, next) => {
  // 预检请求处理
  if (req.method === 'OPTIONS') {
    res.status(200).end();
    return;
  }
  next();
});

// 静态文件服务
app.use(express.static(path.join(currentDir, './public')));

// 速率限制
if (config.RATE_LIMIT_ENABLED) {
  const limiter = rateLimit({
    windowMs: config.RATE_LIMIT_WINDOW_MS, // 15分钟
    max: config.RATE_LIMIT_MAX, // 限制每个IP 15分钟内最多100个请求
    message: {
      success: false,
      message: '请求过于频繁，请稍后再试',
    },
  });
  app.use('/api', limiter);
}

// 初始化认证
configureJwtStrategy(config.JWT_SECRET);
configureLocalStrategy();
initializePassport();

// 主页路由
app.get('/', (_req, res) => {
  res.sendFile(path.join(currentDir, './public/index.html'));
});

// 健康检查端点
app.get('/health', (_req, res) => {
  res.json({
    success: true,
    message: '服务运行正常',
    timestamp: new Date(),
    uptime: process.uptime(),
  });
});

// API路由
app.get('/api/status', (_req, res) => {
  res.json({
    success: true,
    data: {
      status: 'running',
      version: '1.0.0',
      timestamp: new Date(),
    },
  });
});

// 认证路由
app.post('/api/auth/login', (req, res) => {
  const { email, password } = req.body;

  // 简单的认证逻辑（演示用）
  if (email === 'admin@example.com' && password === 'admin123') {
    const token = generateToken(
      { userId: '1', email: 'admin@example.com' },
      config.JWT_SECRET,
      '1h',
    );

    res.json({
      success: true,
      data: {
        token,
        user: {
          id: '1',
          email: 'admin@example.com',
          username: 'admin',
        },
      },
    });
  } else {
    res.status(401).json({
      success: false,
      message: '邮箱或密码错误',
    });
  }
});

// 受保护的路由示例
app.get('/api/protected', (_req, res) => {
  res.json({
    success: true,
    message: '这是受保护的路由',
    data: {
      timestamp: new Date(),
      user: (_req as any).user || '未认证',
    },
  });
});

// 用户路由
app.get('/api/users', (_req, res) => {
  res.json({
    success: true,
    data: [
      {
        id: '1',
        username: 'admin',
        email: 'admin@example.com',
        role: 'admin',
      },
      {
        id: '2',
        username: 'user1',
        email: 'user1@example.com',
        role: 'user',
      },
    ],
  });
});

// 聊天室路由
app.get('/api/rooms', (_req, res) => {
  res.json({
    success: true,
    data: [
      { id: 'general', name: '通用聊天室', users: 5 },
      { id: 'tech', name: '技术讨论', users: 3 },
      { id: 'random', name: '随机话题', users: 2 },
    ],
  });
});

// 错误处理中间件 - Express 5.x 兼容
app.use(
  (
    err: any,
    _req: express.Request,
    res: express.Response,
    next: express.NextFunction,
  ) => {
    console.error('错误:', err);
    res.status(500).json({
      success: false,
      message: '服务器内部错误',
      error: config.NODE_ENV === 'development' ? err.message : '未知错误',
    });
    next();
  },
);

// 404处理 - Express 5.x 兼容
app.use((_req, res) => {
  res.status(404).json({
    success: false,
    message: '路由不存在',
  });
});

// 初始化WebSocket服务
const _wsService = new WebSocketService(server);
// 暂时不使用 WebSocket 服务，但保留以备将来使用
void _wsService;

// 启动服务器
async function startServer() {
  try {
    // 验证配置
    validateConfig();
    console.log(config, '---config---');
    // 连接MySQL数据库（可选）
    if (config.MYSQL_HOST) {
      try {
        await mysqlConnection.connect({
          host: config.MYSQL_HOST,
          port: config.MYSQL_PORT,
          username: config.MYSQL_USERNAME,
          password: config.MYSQL_PASSWORD,
          database: config.MYSQL_DATABASE,
          dialect: 'mysql',
          pool: {
            max: 10,
            min: 0,
            acquire: 30000,
            idle: 10000,
          },
          logging: config.NODE_ENV === 'development',
        });

        // 同步数据库模型
        await mysqlConnection.sync(false);
        // 初始化数据模型
        initializeModels();
        console.log('✅ MySQL 数据库连接成功');
      } catch (error) {
        console.warn(
          '⚠️ MySQL 数据库连接失败，继续启动服务:',
          (error as Error).message,
        );
      }
    } else {
      console.log('ℹ️ 未配置 MySQL 数据库，跳过数据库连接');
    }

    // 连接Redis（可选）
    if (config.REDIS_HOST) {
      try {
        const redisConfig: any = {
          host: config.REDIS_HOST,
          port: config.REDIS_PORT,
          db: config.REDIS_DB,
          keyPrefix: config.REDIS_KEY_PREFIX,
        };

        // 只有当 password 存在时才添加到配置中
        if (config.REDIS_PASSWORD) {
          redisConfig.password = config.REDIS_PASSWORD;
        }

        await redisConnection.connect(redisConfig);
        console.log('✅ Redis 连接成功');
      } catch (error) {
        console.warn(
          '⚠️ Redis 连接失败，继续启动服务:',
          (error as Error).message,
        );
      }
    } else {
      console.log('ℹ️ 未配置 Redis，跳过缓存连接');
    }

    server.listen(port, config.HOST, () => {
      console.log(`🚀 服务器启动成功！`);
      console.log(`📍 地址: http://${config.HOST}:${port}`);
      console.log(`🔌 WebSocket: ws://${config.HOST}:${port}/ws`);
      console.log(`📊 健康检查: http://${config.HOST}:${port}/health`);
      console.log(`🌍 环境: ${config.NODE_ENV}`);
    });
  } catch (error) {
    console.error('启动服务器失败:', error);
    process.exit(1);
  }
}

// 优雅关闭
process.on('SIGTERM', async () => {
  console.log('收到 SIGTERM 信号，正在关闭服务器...');
  await mysqlConnection.disconnect();
  await redisConnection.disconnect();
  server.close(() => {
    console.log('服务器已关闭');
    process.exit(0);
  });
});

process.on('SIGINT', async () => {
  console.log('收到 SIGINT 信号，正在关闭服务器...');
  await mysqlConnection.disconnect();
  await redisConnection.disconnect();
  server.close(() => {
    console.log('服务器已关闭');
    process.exit(0);
  });
});

// 启动服务器
startServer();
